/*
 * @Author: xuetao 3168581151@qq.com
 * @Date: 2025-01-28
 * @LastEditors: xuetao 3168581151@qq.com
 * @LastEditTime: 2025-01-30
 * @Description: Preferences 持久化服务（单例模式, 饿汉式）
 */
import 'dart:convert';

import 'package:shared_preferences/shared_preferences.dart';

class Preferences {
  // 私有构造函数，防止外部实例化
  Preferences._internal();

  // 静态变量，保存Preferences的唯一实例
  static final Preferences _instance = Preferences._internal();

  // SharedPreferences 实例
  late SharedPreferences _prefs;

  // getter 提供公共获取点（Preferences.instance）
  static Preferences get instance => _instance;

  /// 异步初始化方法（必须在首次使用前调用）
  static Future<void> init() async {
    // 把SharedPreferences 实例 赋值给Preferences的实例的_prefs属性
    instance._prefs = await SharedPreferences.getInstance();
  }

  /// 通用方法：获取数据
  T? get<T>(String key) {
    try {
      switch (T) {
        case String:
          return _prefs.getString(key) as T?;
        case int:
          return _prefs.getInt(key) as T?;
        case double:
          return _prefs.getDouble(key) as T?;
        case bool:
          return _prefs.getBool(key) as T?;
        case List:
          return _prefs.getStringList(key) as T?;
        default:
          return null;
      }
    } catch (e) {
      throw Exception('获取数据失败');
    }
  }

  /// 通用方法：设置数据
  Future<void> set<T>(String key, T value) async {
    switch (T) {
      case String:
        await _prefs.setString(key, value as String);
        break;
      case int:
        await _prefs.setInt(key, value as int);
        break;
      case double:
        await _prefs.setDouble(key, value as double);
        break;
      case bool:
        await _prefs.setBool(key, value as bool);
        break;
      case List:
        await _prefs.setStringList(key, value as List<String>);
        break;
      default:
        throw Exception('类型不合法 ,${T.toString()}');
    }
  }

  /// 通用方法：清除数据
  Future<bool> remove(String key) async {
    try {
      return await _prefs.remove(key);
    } catch (e) {
      throw Exception('清除数据失败');
    }
  }

  /// 存储对象,将对象转换为json字符串存储
  Future<bool> setObject(String key, Object value) {
    final jsonString = jsonEncode(value);
    return _prefs.setString(key, jsonString);
  }

  /// 获取对象,将json字符串转换为对象
  T? getObject<T>(String key) {
    final jsonString = _prefs.getString(key);
    if (jsonString == null) return null;
    return jsonDecode(jsonString);
  }
}
